﻿namespace BlogsAPI.Rdf
{
    using System.Xml.Serialization;

    /// <summary>
    /// Agent - An agent (eg. person, group, software or physical artifact).
    /// </summary>
    /// <remarks>
    /// Tested with 
    /// http://www.liveinternet.ru/users/flashr/foaf/ 
    /// http://community.livejournal.com/ktosomnoi/data/foaf
    /// http://dolboeb.livejournal.com/data/foaf
    /// http://flashr.ya.ru/foaf.xml
    /// http://clubs.ya.ru/ya/foaf.xml
    /// http://eikeon.com/foaf.rdf
    /// http://madskristensen.net/foaf.axd - foaf:PersonalProfileDocument ignored
    /// </remarks>
    [XmlRoot("Agent", Namespace = "http://xmlns.com/foaf/0.1/")]
    public class FoafAgent : RdfElement
    {
        #region Foaf:Agent.Core

        /// <summary>
        /// FOAF provides some other naming constructs. While foaf:name does not explicitly represent name substructure (family vs given etc.) it does provide a basic level of interoperability. See the issue tracker for status of work on this issue. 
        /// The foaf:name property, like all RDF properties with a range of rdfs:Literal, may be used with XMLLiteral datatyped values. This usage is, however, not yet widely adopted. Feedback on this aspect of the FOAF design is particularly welcomed.
        /// </summary>
        /// <value>A name for some thing.</value>
        /// <example><foaf:name xml:lang="en">Dan Brickley</foaf:name></example>
        [XmlElement("name", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string Name { get; set; }

        /// <summary>
        /// The foaf:nick property relates a foaf:Person to a short (often abbreviated) nickname, 
        /// such as those use in IRC chat, online accounts, and computer logins. 
        /// This property is necessarily vague, because it does not indicate any particular
        /// naming control authority, and so cannot distinguish a person's login from their 
        /// (possibly various) IRC nicknames or other similar identifiers. However it has some utility, 
        /// since many people use the same string (or slight variants) across a variety of such environments.
        /// </summary>
        /// <value>A short informal nickname characterising an agent (includes login identifiers, IRC and other chat nicknames).</value>
        /// <example><foaf:name xml:lang="en">Dan Brickley</foaf:name></example>
        /// <remarks>Moved from Person to Agent</remarks>
        [XmlElement("nick", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string Nick { get; set; }

        /// <summary>
        /// The foaf:birthday property is a relationship between a foaf:Agent and a string representing 
        /// the month and day in which they were born (Gregorian calendar). 
        /// See BirthdayIssue for details of related properties that can be used to describe such things 
        /// in more flexible ways.
        /// </summary>
        /// <value>The birthday of this Agent, represented in mm-dd string form, eg. '12-31'.</value>
        [XmlElement("birthday", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string BirthDay { get; set; }


        /// <summary>
        /// The foaf:gender property relates a foaf:Agent (typically a foaf:Person) to a string representing
        /// its gender. In most cases the value will be the string 'female' or 'male' (in lowercase without 
        /// surrounding quotes or spaces). Like all FOAF properties, there is in general no requirement to use 
        /// foaf:gender in any particular document or description. Values other than 'male' and 'female' may be 
        /// used, but are not enumerated here. The foaf:gender mechanism is not intended to capture the full 
        /// variety of biological, social and sexual concepts associated with the word 'gender'.
        /// </summary>
        /// <value>The gender of this Agent (typically but not necessarily 'male' or 'female').</value>
        /// <remarks>Can be NULL</remarks>
        [XmlElement("gender", Namespace = "http://xmlns.com/foaf/0.1/")]
        public FoafGender? Gender { get; set; }

        /// <summary>
        /// The foaf:mbox property is a relationship between the owner of a mailbox and a mailbox. These are typically identified using the mailto: URI scheme (see RFC 2368). 
        /// There are many mailboxes (eg. shared ones) which are not the foaf:mbox of anyone. Furthermore, a person can have multiple foaf:mbox properties.
        /// </summary>
        /// <value>A personal mailbox, ie. an Internet mailbox associated with exactly one owner, 
        /// the first owner of this mailbox. This is a 'static inverse functional property', 
        /// in that there is (across time and change) 
        /// at most one individual that ever has any particular value for foaf:mbox.</value>
        [XmlElement("mbox", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string Email { get; set; }


        /// <summary>
        /// A foaf:mbox_sha1sum of a foaf:Person is a textual representation of the result of applying the SHA1
        ///  mathematical functional to a 'mailto:' identifier (URI) for an Internet mailbox that they stand 
        /// in a foaf:mbox relationship to. In other words, if you have a mailbox (foaf:mbox) but don't want 
        /// to reveal its address, you can take that address and generate a foaf:mbox_sha1sum representation of it. 
        /// Just as a foaf:mbox can be used as an indirect identifier for its owner, we can do the same with 
        /// foaf:mbox_sha1sum since there is only one foaf:Person with any particular value for that property.
        /// </summary>
        /// <value> The sha1sum of the URI of an Internet mailbox associated with exactly one owner, the first owner of the mailbox.</value>
        [XmlElement("mbox_sha1sum", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string EmailSha1 { get; set; }

        /// <summary>
        /// A weblog of some thing (whether person, group, company etc.).
        /// </summary>
        [XmlElement("weblog", Namespace = "http://xmlns.com/foaf/0.1/")]
        public WeblogExt Weblog { get; set; }

        /// <summary>
        /// The foaf:homepage property relates something to a homepage about it. 
        /// Many kinds of things have homepages. FOAF allows a thing to have multiple homepages, 
        /// but constrains foaf:homepage so that there can be only one thing that has any particular homepage
        /// </summary>
        /// <value>A homepage for some thing.</value>
        [XmlElement("homepage", Namespace = "http://xmlns.com/foaf/0.1/")]
        public RdfElement HomePage { get; set; }

        /// <summary>A foaf:openid is a property of a foaf:Agent that associates it with a document that can 
        /// be used as an indirect identifier in the manner of the OpenID "Identity URL". 
        /// As the OpenID 1.1 specification notes, OpenID itself"does not provide any mechanism to exchange 
        /// profile information, though Consumers of an Identity can learn more about an End User from any public,
        /// semantically interesting documents linked thereunder (FOAF, RSS, Atom, vCARD, etc.)". 
        /// In this way, FOAF and OpenID complement each other; neither provides a stand-alone approach 
        /// to online "trust", but combined they can address interesting parts of this larger problem space.
        /// </summary>
        /// <value>An OpenID for an Agent.</value>
        [XmlElement("openid", Namespace = "http://xmlns.com/foaf/0.1/")]
        public RdfElement OpenID { get; set; }

        /// <summary>
        /// The foaf:page property relates a thing to a document about that thing.
        /// </summary>
        /// <value>A page or document about this thing.</value>
        [XmlArray("page")]
        [XmlArrayItem("Document",Type = typeof(RdfElement),
            Namespace = "http://xmlns.com/foaf/0.1/")]
        public RdfElement[] Pages { get; set; }

        /// <summary>
        /// The foaf:img property relates a foaf:Person to a foaf:Image that represents them. 
        /// Unlike its super-property foaf:depiction, we only use foaf:img when an image is particularly representative of some person. 
        /// The analogy is with the image(s) that might appear on someone's homepage, rather than happen to appear somewhere in their photo album.
        /// </summary>
        /// <value>An image that can be used to represent some thing (ie. those depictions which are particularly representative of something, eg. one's photo on a homepage).</value>
        /// <example><foaf:img>http://img.sex.ru/userpic/1051645/90316</foaf:img></example>
        /// <remarks>Array of Images</remarks>
        [XmlElement("img", Namespace = "http://xmlns.com/foaf/0.1/")]
        public RdfElement[] Images { get; set; }

        /// <summary>
        /// The foaf:jabberID property relates a foaf:Agent to a textual identifier assigned to them in 
        /// the Jabber messaging system. See the Jabber site for more information about the Jabber 
        /// protocols and tools.
        /// </summary>
        /// <value>A jabber ID for something..</value>
        [XmlElement("jabberID", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string JabberID { get; set; }

        /// <summary>
        /// The foaf:icqChatID property relates a foaf:Agent to a textual identifier assigned to them 
        /// in the ICQ Chat system. See the icq chat site for more details of the 'icq' service. 
        /// Their "What is ICQ?" document provides a basic overview, while their "About Us page notes that 
        /// ICQ has been acquired by AOL. Despite the relationship with AOL, ICQ is at the time of writing 
        /// maintained as a separate identity from the AIM brand (see foaf:aimChatID).
        /// </summary>
        /// <value>An ICQ chat ID</value>
        [XmlElement("icqChatID", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string IcqChatID { get; set; }

        /// <summary>
        /// The foaf:aimChatID property relates a foaf:Agent to a textual identifier ('screenname')
        /// assigned to them in the AOL Instant Messanger (AIM) system. 
        /// See AOL's AIM site for more details of AIM and AIM screennames. 
        /// The iChat tools from Apple also make use of AIM identifiers.
        /// </summary>
        /// <value>An AIM chat ID</value>
        [XmlElement("aimChatID", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string AimChatID { get; set; }

        /// <summary>
        /// The foaf:msnChatID property relates a foaf:Agent to a textual identifier assigned to them in the MSN
        /// online Chat system. See Microsoft's the MSN chat site for more details (or for a message saying 
        /// "MSN Chat is not currently compatible with your Internet browser and/or computer operating system"
        /// if your computing platform is deemed unsuitable).
        /// </summary>
        /// <value>An MSN chat ID</value>
        [XmlElement("msnChatID", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string MsnChatID { get; set; }

        /// <summary>
        /// The foaf:yahooChatID property relates a foaf:Agent to a textual identifier assigned 
        /// to them in the Yahoo online Chat system. See Yahoo's the Yahoo! Chat site for more details 
        /// of their service. Yahoo chat IDs are also used across several other Yahoo services, 
        /// including email and Yahoo! Groups.
        /// </summary>
        /// <value>A Yahoo chat ID</value>
        [XmlElement("yahooChatID", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string YahooChatID { get; set; }

        /// <summary>
        /// Additional resource!
        /// </summary>
        [XmlElement("seeAlso", Namespace = "http://www.w3.org/2000/01/rdf-schema#")]
        public RdfElement[] SeeAlso { get; set; }

        /// <summary>
        /// Additional resource!
        /// </summary>
        [XmlElement("isDescribedIn", Namespace = "http://xmlns.com/foaf/0.1/")]
        public RdfElement isDescribedIn
        {
            get { return(SeeAlso==null||SeeAlso.Length==0)?null:SeeAlso[0];}
            set
            {
                if (SeeAlso == null || SeeAlso.Length == 0) SeeAlso = new[] {value};
                else
                {
                    SeeAlso[0] = value;
                }
            }
        }

        /// <summary>
        /// This approach to characterising interests is intended to compliment other mechanisms 
        /// (such as the use of controlled vocabulary). It allows us to use a widely known set of unique identifiers 
        /// (Web page URIs) with minimal pre-coordination. Since URIs have a controlled syntax, this makes data merging 
        /// much easier than the use of free-text characterisations of interest. 
        /// Interest does not imply expertise, and that this FOAF term provides no support for characterising 
        /// levels of interest: passing fads and lifelong quests are both examples of someone's foaf:interest. 
        /// Describing interests in full is a complex undertaking; foaf:interest provides one basic component 
        /// of FOAF's approach to these problems.
        /// </summary>
        [XmlElement("interest", Namespace = "http://xmlns.com/foaf/0.1/")]
        public RdfElement[] Interests { get; set; }

        /// <summary>
        /// The foaf:knows property relates a foaf:Person to another foaf:Person that he or she knows. 
        /// We take a broad view of 'knows', but do require some form of reciprocated interaction 
        /// (ie. stalkers need not apply). Since social attitudes and conventions on this topic vary greatly 
        /// between communities, counties and cultures, it is not appropriate for FOAF to be overly-specific here.
        /// </summary>
        /// <value>A person known by this person (indicating some level of reciprocated interaction between the parties).</value>
        [XmlElement("knows", Namespace = "http://xmlns.com/foaf/0.1/")]
        public FoafKnow[] Knows { get; set; }

        #endregion

        #region Some fields defined by Yandex


        /// <summary>
        /// Свойство ya:bio содержит биографию человека в свободной форме.
        /// </summary>
        [XmlElement("bio", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public string Bio { get; set; }

        /// <summary>
        /// Свойство ya:address содержит информацию об адресе пользователя. 
        /// В атрибуте dc:title указывается фактический адрес, а в атрибуте rdf:resource - URL, 
        /// однозначно его идентифицирующий. Для этого может быть использован URL на Яндекс.Картах.
        /// </summary>
        [XmlElement("address", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public RdfElement Address { get; set; }

        /// <summary>
        /// Свойство ya:сity содержит информацию о городе. 
        /// В атрибуте dc:title указывается название города, а в атрибуте rdf:resource - URL,
        /// однозначно его идентифицирующий. Для этого может быть использован URL на Яндекс.Картах.
        /// </summary>
        [XmlElement("city", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public RdfElement City { get; set; }

        /// <summary>
        /// Свойство ya:region содержит информацию об области или регионе. 
        /// В атрибуте dc:title указывается название области или региона, а в атрибуте rdf:resource - URL,
        ///  однозначно его идентифицирующий. Для этого может быть использован URL на Яндекс.Картах.
        /// </summary>
        [XmlElement("region", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public RdfElement Region { get; set; }

        /// <summary>
        /// Свойство ya:сountry содержит информацию о стране. 
        /// В атрибуте dc:title указывается название страны, а в атрибуте rdf:resource - URL, 
        /// однозначно ее идентифицирующий. Для этого может быть использован URL на Яндекс.Картах.
        /// </summary>
        [XmlElement("country", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public RdfElement Country { get; set; }

        /// <summary>
        /// Свойство ya:сountry содержит информацию о стране. 
        /// В атрибуте dc:title указывается название страны, а в атрибуте rdf:resource - URL, 
        /// однозначно ее идентифицирующий. Для этого может быть использован URL на Яндекс.Картах.
        /// </summary>
        /// <remarks>Needs for correct parsing</remarks>
        /// <example><ya:location ya:country="Россия" ya:region="Москва" ya:city="Москва" ya:address="" /></example>
        [XmlElement("location", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public YaLocation Location
        {
            get
            {
                if (City == null && Region == null && Country==null && Address==null) return null;
                return new YaLocation
                           {
                               City = City==null?"":City.Resource,
                               Region = Region == null ? "" : Region.Resource,
                               Country = Country == null ? "" : Country.Resource,
                               Address = Address == null ? "" : Address.Resource
                           };
            }
            set {
                City = new RdfElement {Resource = value.City};
                Region = new RdfElement { Resource = value.Region };
                Address = new RdfElement { Resource = value.Address };
                Country = new RdfElement { Resource = value.Country };
            }
        }

        

        /// <summary>
        /// Some systems like Yandex
        /// use "dateOfBirth" instead of "birthday"
        /// </summary>
        [XmlElement("dateOfBirth", Namespace = "http://xmlns.com/foaf/0.1/")]
        public string DateOfBirth
        {
            get { return BirthDay; }
            set { BirthDay = value; }
        }

        /// <summary>
        /// Свойство ya:blogActivity содержит информацию об одном из видов активности в блоге, 
        /// связанной с добавлением или удалением комментариев (ya:Comments), записей (ya:Posts), 
        /// ссылок (ya:Links) и читателей (ya:Readers).
        /// </summary>
        [XmlElement("blogActivity", Namespace = "http://blogs.yandex.ru/schema/foaf/")]
        public BlogActivityClass[] Activities { get; set; }

        #endregion
    }
}
